package com.ytjj.common.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * 订单编码码生成器，生成32位数字编码，
 * @生成规则 1位单号类型+17位时间戳+14位(用户id加密&随机数)
 *
 * @version 1.0
 *
 */
public class OrderUtils {

    /**
     * 订单类别头
     */

    private static final String ORDER_CODE = "B";

    /**
     * 子订单类别头
     */

    private static final String CHILD_ORDER_CODE = "NN";

    /**
     * 订单类别头
     */

    private static final String PHONE_ORDER_CODE = "P";

    /**
     * 订单类别头
     */

    private static final String PAY_ORDER_CODE = "PAYA";
    /**
     * 退货类别头
     */

    private static final String RETURN_ORDER = "S";
    /**
     * 退款类别头
     */

    private static final String REFUND_ORDER = "YB";

    /**
     * 购物车商品
     */
    private static final String CART_PRO = "NN";

    /**
     * 账号前缀
     */
    private static final String ACCOUNT_PREFIX = "GB";
    /**
     * 商品
     */
    private static final String PRODUCT = "P";
    /**
     * 购物卡
     */
    private static final String SHOPPING_CARD = "NO";

    /**
     * 报销单
     */
    private static final String REIMBURSEMENT_PRE = "EA";

    /**
     * 随即编码
     */

    private static final int[] r = new int[]{7, 9, 6, 2, 8, 1, 3, 0, 5, 4};

    /**
     * 用户id和随机数总长度
     */
    private static final int maxLength = 6;

    /**
     * 根据id进行加密+加随机数组成固定长度编码
     */
    private static String toCode(Integer userId) {
        String idStr = userId.toString();
        StringBuilder idsbs = new StringBuilder();
        for (int i = idStr.length() - 1; i >= 0; i--) {
            idsbs.append(r[idStr.charAt(i) - '0']);
        }
        return idsbs.append(getRandom(maxLength - idStr.length())).toString();
    }


    // G20210622 + 10位自增 + 6位随机
    public static String generateOrderNo() {
        return getDateTime();
    }

    // 6位定长随机数
    public static String generateRandom() {
        Random random = new Random();
        int randomVal = random.nextInt(99999);
        StringBuilder result = new StringBuilder("");
        switch (String.valueOf(randomVal).length()) {
            case 1 :
                result.append("0000").append(randomVal);
                break;
            case 2 :
                result.append("000").append(randomVal);
                break;
            case 3 :
                result.append("00").append(randomVal);
                break;
            case 4 :
                result.append("0").append(randomVal);
                break;
            default :
                result.append(randomVal);
                break;
        }
        return result.toString();
    }

    /**
     * 生成时间戳
     */
    private static String getDateTime() {
        DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date());
    }
    /**
     * 生成时间戳
     */
    private static String getNewDateTime() {
        DateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(new Date());
    }

    /**
     * 生成固定长度随机码
     *
     * @param n 长度
     */

    private static long getRandom(long n) {
        long min = 1, max = 9;
        for (int i = 1; i < n; i++) {
            min *= 10;
            max *= 10;
        }
        long rangeLong = (((long) (new Random().nextDouble() * (max - min)))) + min;
        return rangeLong;
    }


    /**
     * 生成不带类别标头的编码
     *
     * @param userId
     */
    private static synchronized String getCode(Integer userId) {
        userId = userId == null ? 10000 : userId;
        return getDateTime() + toCode(userId);
    }


    /**
     * 生成订单单号编码(调用方法)
     * @param userId  网站中该用户唯一ID 防止重复
     */

    public static String getOrderCode(Integer userId) {
        return ORDER_CODE + getCode(userId);
    }


    /**
     * 生成订单单号编码(调用方法)
     *
     * G + 时间戳8位数 + 随机10位数
     */
    public static String getNewOrderCode() {
        return ORDER_CODE + getNewDateTime() + getNewCode();
    }

    /**
     * 生成订单单号编码(调用方法)
     *
     * G + 时间戳8位数 + 随机10位数
     */
    public static String getChildOrderNo(String orderSource) {
        Integer num = 0;
        switch(orderSource){
            case "h5" :
                num = 1;
                break;
            case "android" :
                num = 2;
                break;
            case "ios" :
                num = 3;
                break;
            case "weapp" :
                num = 4;
                break;
            case "quickapp" :
                num = 5;
                break;
            case "wx" :
                num = 6;
                break;
            case "pc" :
                num = 7;
                break;
        }
        return CHILD_ORDER_CODE + getNewDateTime() + num + getChildCode();
    }

    public static synchronized void main(String[] args) {
//        long l1 = System.currentTimeMillis();
//        Set<Integer> set1 = new HashSet<>();
//        for (int q = 0; q < 1000; q++) {
//            Set<String> set = new HashSet<>();
//            for (int i = 0; i < 10000; i++) {
//                String newOrderCode = getNewOrderCode();
//                set.add(newOrderCode);
//            }
//            System.out.println(set.size());
//            set1.add(set.size());
//        }
//        for (Integer integer : set1) {
//            System.out.println(integer);
//        }
//
//        long l2 = System.currentTimeMillis();
//        System.out.println(l2 - l1);
        System.out.println(UUID.randomUUID().toString().replaceAll("-", ""));
    }

    /**
     * 随机生成10位数
     * @return
     */
    public static synchronized StringBuilder getNewCode() {
        StringBuilder idsbs = new StringBuilder();
        for (int i = 0; i <10 ; i++) {
            int v = (int) (Math.random() * 10);
            idsbs.append(v);
        }
        return idsbs;
    }

    /**
     * 随机生成9位数
     * @return
     */
    public static synchronized StringBuilder getChildCode() {
        StringBuilder idsbs = new StringBuilder();
        for (int i = 0; i <9 ; i++) {
            int v = (int) (Math.random() * 10);
            idsbs.append(v);
        }
        return idsbs;
    }

    /**
     * 生成话费订单单号编码(调用方法)
     */

    public static String getPhoneOrderCode() {
        return PHONE_ORDER_CODE + getCode(null);
    }

    /**
     * 生成订单单号编码(调用方法)
     * @param userId  网站中该用户唯一ID 防止重复
     */

    public static String getPayOrderCode(Integer userId) {
        return PAY_ORDER_CODE + getCode(userId);
    }


    /**
     * 生成退货单号编码（调用方法）
     * @param userId 网站中该用户唯一ID 防止重复
     */
    public static String getReturnCode(Integer userId) {
        return RETURN_ORDER + getCode(userId);
    }


    /**
     * 生成退款单号编码(调用方法)
     * @param userId  网站中该用户唯一ID 防止重复
     */
    public static String getRefundCode(Integer userId) {
        return REFUND_ORDER + getCode(userId);
    }

    /**
     * 生成报销单号编码(调用方法)
     * @param userId  网站中该用户唯一ID 防止重复
     */
    public static String getReimbursementCode(Integer userId) {
        return REIMBURSEMENT_PRE + getCode(userId);
    }

    /**
     * 生成提现单号编码(调用方法)
     * @param userId  网站中该用户唯一ID 防止重复
     */
    public static String getWithdrawalCode(Integer userId) {
        return REFUND_ORDER + getCode(userId);
    }

    /**
     * 生成购物车编码(调用方法)
     * @param id  网站中该用户唯一ID 防止重复
     */
    public static String getCartCode(Integer id) {
        return CART_PRO + getCode(id);
    }

    public static String getRandomAccount() {
        return ACCOUNT_PREFIX + getCode(null);
    }


    public static String getProductNo() {
        return PRODUCT + getCode(null);
    }

    public static String getShoppingCard(){
        return SHOPPING_CARD+"80"+getRandom(6);
    }
}
